 package com.handong.handserialprogram.module.catchcriminal;

import android.content.DialogInterface;
import android.text.TextUtils;
import android.view.KeyEvent;

import com.afollestad.materialdialogs.MaterialDialog;
import com.amap.api.location.AMapLocation;
import com.amap.api.maps.AMap;
import com.amap.api.maps.AMapUtils;
import com.amap.api.maps.CameraUpdateFactory;
import com.amap.api.maps.model.LatLng;
import com.amap.api.maps.model.LatLngBounds;
import com.amap.api.maps.model.Marker;
import com.amap.api.services.core.AMapException;
import com.amap.api.services.core.LatLonPoint;
import com.amap.api.services.geocoder.GeocodeResult;
import com.amap.api.services.geocoder.GeocodeSearch;
import com.amap.api.services.geocoder.RegeocodeQuery;
import com.amap.api.services.geocoder.RegeocodeResult;
import com.handong.handserialprogram.R;
import com.handong.handserialprogram.model.entities.FootRingNewEntity;
import com.handong.handserialprogram.model.entities.MapPersonEntity;
import com.handong.handserialprogram.model.status.EmergencyMsg;
import com.handong.handserialprogram.model.status.EmergencyResponse;
import com.handong.handserialprogram.model.status.FootRingStatus;
import com.handong.handserialprogram.module.baiduoverlay.DrivingRouteOverlay;
import com.handong.handserialprogram.module.base.BasePresenter;
import com.handong.handserialprogram.module.base.BaseView;
import com.handong.handserialprogram.utils.EventBusUtil;
import com.handong.handserialprogram.utils.FootRingNewUtil;
import com.handong.handserialprogram.utils.JLog;
import com.handong.handserialprogram.utils.SystemUtil;

import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;

import java.util.HashMap;
import java.util.concurrent.CopyOnWriteArrayList;

/**
 * Created by userKey on 2017/9/18.
 */

public class CatchCriminalPresenter extends BasePresenter<CatchCriminalActivity> implements GeocodeSearch.OnGeocodeSearchListener,
        AMap.OnMarkerClickListener, DrivingRouteOverlay.OnMarkerClick {

    protected static final String TAG = CatchCriminalPresenter.class.getSimpleName();
    protected String PoliceMarker = "POLICE_MARKER";
    protected String CriminalMarker = "CRIMINAL_MARKER";
    private HashMap<String, Marker> mMarkerMap;
    //private RoutePlanSearch mRoutePlanSearch;
    private LatLng mStartLatLng, mEndLatLng;
    private DrivingRouteOverlay mRouteOverlay;
    private FootRingNewEntity mRingEntity;
    private MaterialDialog mLocatingDialog;

    private String mRingID = null;

    private boolean mIsCriminal = false;
    private int mMapStatus = 0;
    GeocodeSearch geocoderSearch;


    public CatchCriminalPresenter(BaseView view) {
        super(view);
        mMarkerMap = new HashMap<>();

        mLocatingDialog = new MaterialDialog.Builder(mView)
                .progress(true, 0)
                .content(R.string.dialog_content_loading_map)
                .canceledOnTouchOutside(false)
                .build();
        mLocatingDialog.setOnKeyListener(new DialogInterface.OnKeyListener() {
            @Override
            public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) {
                if (KeyEvent.KEYCODE_BACK == keyCode) {
                    dialog.dismiss();
                    if (mView != null) mView.finish();
                    return true;
                }
                return false;
            }
        });
        mLocatingDialog.show();
        try {
            geocoderSearch = new GeocodeSearch(mView);
        } catch (AMapException e) {
            e.printStackTrace();
        }
        geocoderSearch.setOnGeocodeSearchListener(this);
    }

    protected void initMapModule(String ringID) {
        EventBusUtil.register(this);
        mView.getAMap().setOnMarkerClickListener(this);
        mRingID = ringID;
        mMapStatus = BOTTOM_STATUS.HIDE.ordinal();
    }

    @Override
    public boolean onMarkerClick(Marker marker) {
        if (mRouteOverlay == null) {
            if (mMarkerMap.get(PoliceMarker).equals(marker)) {
                return startMarkerClick(marker);
            } else {
                return endMarkerClick(marker);
            }

        } else {
            return mRouteOverlay.onOverlayMarkerClick(marker);
        }
    }

    protected void backupRingID(String id) {
        mRingID = id;
    }

    @Subscribe(threadMode = ThreadMode.MAIN, priority = 5)
    public void receiveFootRingList(CopyOnWriteArrayList<FootRingNewEntity> vector) {
        if (mView == null || !mView.isResume()) {
            return;
        }
        if (!TextUtils.isEmpty(mRingID)) {
            FootRingNewEntity entity = FootRingNewUtil.findFootRingById(vector, mRingID);
            if (entity != null) {
                mRingEntity = entity;
            } else {
                if (mRingEntity == null) {
                    mRingEntity = vector.get(0);
                }
            }
        } else return;

        if (mRouteOverlay == null && mRingEntity.getStatus() == FootRingStatus.ESCAPE) {
            if (mStartLatLng != null && mEndLatLng != null) {
                float distance = AMapUtils.calculateLineDistance(mStartLatLng, mEndLatLng);
                if (distance > 1000) {
                    float distanceNew = ((float) distance) / 1000;
                    mView.refreshTipMsg("时间: " + SystemUtil.getDateDetailsString() + "，距犯人: " + String.format("%.1f", distanceNew) + " 千米");
                } else {
                    mView.refreshTipMsg("时间: " + SystemUtil.getDateDetailsString() + "，距犯人: " + String.format("%.1f", distance) + " 米");
                }
            } else {
                mView.refreshTipMsg(R.string.tip_content_criminal_escape);
            }
        } else if (mRouteOverlay == null && mRingEntity.getStatus() == FootRingStatus.NORMAL) {
            mView.refreshTipMsg(R.string.tip_content_criminal_normal);
            Marker criminalMarker = getMarker(CriminalMarker);
            if (criminalMarker != null) {
                criminalMarker.remove();
                mMarkerMap.remove(CriminalMarker);
                mView.hideBottomLayout();
            }

        }
        if (mRouteOverlay != null && mRingEntity.getStatus() == FootRingStatus.NORMAL) {
            AMap map = mView.getAMap();
            map.clear();//清空。
            mRouteOverlay = null;
            mView.addPoliceOnMap(mStartLatLng, R.drawable.map_police_normal);
        }
    }


    @Subscribe(threadMode = ThreadMode.MAIN, priority = 10)
    public void receiveBDLocation(AMapLocation location) {
        if (mView == null) {
            return;
        }
        if (null != mLocatingDialog && mLocatingDialog.isShowing()) {
            mLocatingDialog.dismiss();
            mLocatingDialog = null;
        }
        if (!mView.isResume()) {
            return;
        }
        LatLng latLng = new LatLng(location.getLatitude(), location.getLongitude());
        mStartLatLng = latLng;
        //判断是否生成已规划路线。
        if (mRouteOverlay == null) {
            Marker marker = mMarkerMap.get(PoliceMarker);
            if (null == marker) {
                mView.dismissLoadingDialog();
                mView.addPoliceOnMap(latLng, R.drawable.map_police_normal);
            } else
                marker.setPosition(latLng);
        } else {
            Marker marker = mRouteOverlay.getStartMarker();
            marker.setPosition(latLng);

        }
        if (mMapStatus == BOTTOM_STATUS.POLICE_SHOW.ordinal()) {
            mView.refreshLocateDescription(location.getDescription());
        }
//        zoomToSpan();
    }

    /**
     * 服务器获得中终点信息
     *
     * @param entity
     */
    @Subscribe(threadMode = ThreadMode.MAIN, priority = 60)
    public void receiveCriminalLocate(MapPersonEntity entity) {
        if (!mView.isResume() || mLocatingDialog != null) {
            return;
        }
        if (mRingEntity == null || mRingEntity.getStatus() != FootRingStatus.ESCAPE) {
            return;
        }
        if (TextUtils.isEmpty(mRingID) || !mRingID.equals(entity.getId())) {
            return;
        }
        mEndLatLng = new LatLng(entity.getLat(), entity.getLng());


        //mView.setCstvData( "服务器获取位置 ID="+entity.getId()+"纬度="+entity.getLat()+"经度="+entity.getLng(),"");
        //AppUtil.showShortToast(mView, "ID="+entity.getId()+"纬度="+entity.getLat()+"经度="+entity.getLng());
//        if (mRoutePlanSearch == null) {
//            mRoutePlanSearch = RoutePlanSearch.newInstance();
//            mRoutePlanSearch.setOnGetRoutePlanResultListener(this);
//        }

        //规划路线。
//        PlanNode startNode = PlanNode.withLocation(mStartLatLng);
//        PlanNode endNode = PlanNode.withLocation(latLng);
//        mRoutePlanSearch.drivingSearch(new DrivingRoutePlanOption().from(startNode)
//                .to(endNode)
//                .policy(DrivingRoutePlanOption.DrivingPolicy.ECAR_AVOID_JAM));
        if (mRouteOverlay == null) {
            Marker marker = mMarkerMap.get(CriminalMarker);
            if (null == marker) {
                mView.dismissLoadingDialog();
                mView.addCriminalOnMap(mEndLatLng, R.drawable.map_criminal_escape);
            } else
                marker.setPosition(mEndLatLng);
        } else {
            Marker marker = mRouteOverlay.getStartMarker();
            marker.setPosition(mEndLatLng);

        }
        if (mMapStatus == BOTTOM_STATUS.CRIMINAL_SHOW.ordinal()) {
            LatLonPoint latLonPoint = new LatLonPoint(mEndLatLng.latitude, mEndLatLng.longitude);
            RegeocodeQuery query = new RegeocodeQuery(latLonPoint, 200, GeocodeSearch.AMAP);

            geocoderSearch.getFromLocationAsyn(query);
        }
//        zoomToSpan();
    }

    LatLngBounds.Builder boundsBuilder = new LatLngBounds.Builder();

//    protected void zoomToSpan() {
//        if (mStartLatLng != null) {
//            boundsBuilder.include(mStartLatLng);
//        }
//        if (mEndLatLng != null) {
//            boundsBuilder.include(mEndLatLng);
//        }
//        mView.getmAMap().animateCamera(CameraUpdateFactory.newLatLngBounds(boundsBuilder.build(), 50));
//        mView.getmAMap().animateCamera(CameraUpdateFactory.newLatLngZoom(mStartLatLng, 50));
//    }

    protected void putMarker(String key, Marker marker) {
        mMarkerMap.put(key, marker);
    }

    protected Marker getMarker(String key) {
        if (mMarkerMap.isEmpty()) {
            return null;
        }
        return mMarkerMap.get(key);
    }

    //    @Override
//    public void onGetWalkingRouteResult(WalkingRouteResult walkingRouteResult) {
//        //步行。
//    }
//
//    @Override
//    public void onGetTransitRouteResult(TransitRouteResult transitRouteResult) {
//    }
//
//    @Override
//    public void onGetMassTransitRouteResult(MassTransitRouteResult massTransitRouteResult) {
//    }
//
//    /**
//     * 线路返回
//     * @param drivingRouteResult
//     */
//    @Override
//    public void onGetDrivingRouteResult(DrivingRouteResult drivingRouteResult) {
//        if (null == mView) {
//            return;
//        }
//        if (null == drivingRouteResult || drivingRouteResult.error != SearchResult.ERRORNO.NO_ERROR) {
//            AppUtil.showShortToast(mView, "抱歉，未查找到对应路线");
//            return;
//        }
//        if (drivingRouteResult.getRouteLines().size() == 0) {
//            AppUtil.showShortToast(mView, "抱歉，未查找到对应路线");
//            return;
//        }
//        DrivingRouteLine line = drivingRouteResult.getRouteLines().get(0);
//        if (mRouteOverlay == null) {
//            mRouteOverlay = new DrivingRouteOverlay(mView.getAMap(), line, this);
//            mMarkerMap.clear();
//            mRouteOverlay.addToAMap();
//            mRouteOverlay.zoomToSpan();
//            if(line.getTerminal()!=null){
//                //mView.setCstvData2("初始化犯人","维度="+line.getTerminal().getLocation().latitude+"经度="+line.getTerminal().getLocation().longitude);
//            }
//            if(line.getStarting()!=null){
//                //mView.setCstvData1("初始化警察","维度="+line.getTerminal().getLocation().latitude+"经度="+line.getTerminal().getLocation().longitude);
//            }
//        } else {
//            if(line.getTerminal()!=null){
//               // mView.setCstvData2("犯人","维度="+line.getTerminal().getLocation().latitude+"经度="+line.getTerminal().getLocation().longitude);
//            }
//            if(line.getStarting()!=null){
//                //mView.setCstvData1("警察","维度="+line.getTerminal().getLocation().latitude+"经度="+line.getTerminal().getLocation().longitude);
//            }
//
//
//            mRouteOverlay.updateRouteLine(line);
//            mRouteOverlay.addToAMap();
//        }
//        if (line.getDistance() > 1000) {
//            float distance = ((float) line.getDistance()) / 1000;
//            mView.refreshTipMsg("接收犯人坐标时间: " + SystemUtil.getDateDetailsString() + "，距犯人: " + String.format("%.1f", distance) + " 千米");
//        } else {
//            mView.refreshTipMsg("接收犯人坐标时间: " + SystemUtil.getDateDetailsString() + "，距犯人: " + line.getDistance() + " 米");
//        }
//    }
//
//    @Override
//    public void onGetIndoorRouteResult(IndoorRouteResult indoorRouteResult) {
//    }
//
//    @Override
//    public void onGetBikingRouteResult(BikingRouteResult bikingRouteResult) {
//    }
//
    protected void locateToCenter(AMap AMap) {
        AMap.animateCamera(CameraUpdateFactory.newLatLngZoom(mStartLatLng, 17.0f));
    }
 protected void locateToCenter1(AMap AMap) {
        AMap.animateCamera(CameraUpdateFactory.newLatLngZoom(mEndLatLng, 17.0f));
    }

    @Override
    public boolean startMarkerClick(Marker marker) {
        if (mView == null || mMapStatus == BOTTOM_STATUS.POLICE_SHOW.ordinal()) {
            return true;
        }
        mIsCriminal = false;
        mView.showBottomLayout(mIsCriminal);
        mMapStatus = BOTTOM_STATUS.POLICE_SHOW.ordinal();
        return true;
    }

    @Override
    public boolean endMarkerClick(Marker marker) {
        if (mView == null || mMapStatus == BOTTOM_STATUS.CRIMINAL_SHOW.ordinal()) {
            return true;
        }
        mIsCriminal = true;
        mView.showBottomLayout(mIsCriminal);
        mMapStatus = BOTTOM_STATUS.CRIMINAL_SHOW.ordinal();
        //geoCoderLatLng(marker.getPosition());
        LatLonPoint latLonPoint = new LatLonPoint(marker.getPosition().latitude, marker.getPosition().longitude);
        RegeocodeQuery query = new RegeocodeQuery(latLonPoint, 200, GeocodeSearch.AMAP);

        geocoderSearch.getFromLocationAsyn(query);
        return true;
    }

    protected void resetBottomStatus() {
        mMapStatus = BOTTOM_STATUS.HIDE.ordinal();
    }

//    private void geoCoderLatLng(LatLng latLng){
//        AMapUtil.latLngToAddress(this,latLng, new GeocodeSearch.OnGeocodeSearchListener() {
//            @Override
//            public void onRegeocodeSearched(GeocodeResult geoCodeResult) {
//            }
//
//            @Override
//            public void onRegeocodeSearched(RegeocodeResult reverseGeoCodeResult) {
//                if (null == reverseGeoCodeResult || SearchResult.ERRORNO.NO_ERROR != reverseGeoCodeResult.error) {
//                    JLog.d(TAG, "SearchResult.ERRORNO.NO_ERROR");
//                    return;
//                }
//                JLog.d(TAG, reverseGeoCodeResult.getAddress() + " ||| " + reverseGeoCodeResult.getSematicDescription());
//                mView.refreshLocateDescription(reverseGeoCodeResult.getSematicDescription());
//            }
//        });
//    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    public void receiveEmergencyResult(EmergencyResponse response) {
        if (mView == null || !mView.isResume()) {
            return;
        }
        mView.dealEmergencyResponse(response);
    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    public void receiveEmergencyMsg(EmergencyMsg msg) {
        if (mView == null || !mView.isResume()) {
            return;
        }
        if (msg.isStart()) {
            mView.sendEmergencyRequest();
        } else {
            mView.askUserForEmergency();//弹出报警框
        }
    }

    protected boolean isCanExit() {
        if (mRouteOverlay != null) {
            return false;
        }
        return true;
    }

    protected void forceExit() {
        mRouteOverlay = null;
        mView.finish();
    }

    @Override
    protected void exit() {
        EventBusUtil.unRegister(this);
//        if (mRoutePlanSearch != null) {
//            mRoutePlanSearch.destroy();
//            mRoutePlanSearch = null;
//        }
        if (mRouteOverlay != null) {
            mRouteOverlay.destroy();
            mRouteOverlay = null;
        }
        if (mMarkerMap != null) {
            mMarkerMap.clear();
            mMarkerMap = null;
        }
        mRingEntity = null;
        super.exit();
    }

    @Override
    public void onRegeocodeSearched(RegeocodeResult regeocodeResult, int i) {
        if (null == regeocodeResult || regeocodeResult.getRegeocodeAddress().getFormatAddress().equals("")) {
            JLog.d(TAG, "SearchResult.ERRORNO.NO_ERROR");
            return;
        }
        JLog.d(TAG, regeocodeResult.getRegeocodeAddress().getFormatAddress());
        mView.refreshLocateDescription(regeocodeResult.getRegeocodeAddress().getFormatAddress());
    }

    @Override
    public void onGeocodeSearched(GeocodeResult geocodeResult, int i) {

    }

    protected static enum BOTTOM_STATUS {

        POLICE_SHOW,

        HIDE,

        CRIMINAL_SHOW,
    }
}
